package com.maserb.monitor.job;

import com.alibaba.fastjson.JSONArray;
import com.maserb.monitor.entity.SysCode;
import com.maserb.monitor.entity.schoolStudent.*;
import com.maserb.monitor.model.UploadQuestionModel;
import com.maserb.monitor.model.UploadScoreModel;
import com.maserb.monitor.repository.SysCodeRepository;
import com.maserb.monitor.repository.schoolStudent.*;
import com.maserb.monitor.service.common.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.thymeleaf.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

@Slf4j
@Component
public class Job {
    @Autowired
    private FileService fileService;

    @Autowired
    private SchoolStudentRepository schoolStudentRepository;

    @Autowired
    private StudentScoreRepository studentScoreRepository;

    @Autowired
    private StudentAchieveRepository studentAchieveRepository;

    @Autowired
    private StudentScoreTermRepository studentScoreTermRepository;

    @Autowired
    private SysCodeRepository sysCodeRepository;

    @Autowired
    private StudentErrorBookRepository studentErrorBookRepository;



    /**
     * 解析成绩数据
     *
     * @throws IOException
     */
    @Scheduled(cron = "0 */3 * * * ?")
    public void pullScoreData() {
        try {
            String path = fileService.getUploadDir() + "scores";
            File fileDir = new File(path);
            if(fileDir.exists()) {
                File[] files = fileDir.listFiles();
                for(File file : files) {
                    if(file.isFile()) {
                        String fileName = file.getName();
                        if(!StringUtils.isEmptyOrWhitespace(fileName)) {
                            String folder = fileName.substring(0, fileName.lastIndexOf("."));
                            String unzipFileDir = path + File.separator + folder;
                            File destDir = new File(unzipFileDir);
                            if(!destDir.exists()) {
                                destDir.mkdir();
                            }
                            unzip(file.getAbsolutePath(), unzipFileDir);

                            File[] unzipFiles = destDir.listFiles();
                            for(File subjectFile : unzipFiles) {
                                //科目目录
                                if(subjectFile.isDirectory()) {
                                    File[] scoreFiles = subjectFile.listFiles();

                                    Map<String, UploadQuestionModel> questionMap = new HashMap<>();
                                    for(File questionFile : scoreFiles) {
                                        if(questionFile.getName().startsWith("questions")) {
                                            String data = readFile(questionFile);
                                            List<UploadQuestionModel> questionList = JSONArray.parseArray(data, UploadQuestionModel.class);
                                            for(UploadQuestionModel qm : questionList) {
                                                if(qm != null) {
                                                    questionMap.put(qm.getQuestionNumber(), qm);
                                                }
                                            }
                                            break;
                                        }
                                    }

                                    for(File scoreFile : scoreFiles) {
                                        if(scoreFile.getName().startsWith("scores")) {
                                            String data = readFile(scoreFile);
                                            List<UploadScoreModel> scoreList = JSONArray.parseArray(data, UploadScoreModel.class);
                                            SchoolStudentEntity student;
                                            SysCode subject = null;
                                            StudentScoreTermEntity term = null;
                                            StudentAchieveEntity achieve = null;

                                            if(scoreList.size() > 0 && scoreList.get(0) != null) {
                                                UploadScoreModel firstModel = scoreList.get(0);
                                                subject = sysCodeRepository.findByName(firstModel.getSubjectName());
                                                term = studentScoreTermRepository.findById(firstModel.getExamId()).get();
                                                if(term == null) {
                                                    term = studentScoreTermRepository.findFirstByStatus("1");  //开启成绩上传的考试
                                                }
                                                if(term == null) {
                                                    log.error("term not found, term id :" + firstModel.getExamId());
                                                    continue;
                                                }
                                            }

                                            for(UploadScoreModel model :scoreList) {
                                                student = schoolStudentRepository.findFirstBySchoolIdAndStudentId(model.getSchoolId(), model.getStudentNumber());
                                                if(student == null) {
                                                    log.error("student not found, student number :" + model.getStudentNumber());
                                                    continue;  //如果学生信息不存在，则跳过
                                                }
                                                achieve = studentAchieveRepository.findFirstByStudentAndTermId(student, model.getExamId());
                                                if(achieve == null) {
                                                    achieve = new StudentAchieveEntity();
                                                    achieve.setTerm(term.getTerm());
                                                    achieve.setTermId(term.getId());
                                                    achieve.setClazzId(student.getOrgId());
                                                    achieve.setStudent(student);
                                                    achieve.setAvgScore(0D);
                                                    achieve.setCreateTime(new Date());
                                                    achieve.setSubjectCount(0);
                                                    achieve.setTotalScore(0D);
                                                    studentAchieveRepository.save(achieve);
                                                }

                                                StudentScoreEntity score = studentScoreRepository.findFirstByAchieveAndSubject(achieve, subject);
                                                if(score == null) {
                                                    //重复数据不再入库
                                                    score = new StudentScoreEntity();
                                                    score.setCreateTime(new Date());
                                                    score.setAchieve(achieve);
                                                    score.setScore(Double.valueOf(model.getTotalScore()));
                                                    score.setSubject(subject);

                                                    achieve.setSubjectCount(achieve.getSubjectCount() + 1);
                                                } else {
                                                    score.setScore(score.getScore() + Double.valueOf(model.getTotalScore()));
                                                }

                                                studentScoreRepository.save(score);

                                                achieve.setTotalScore(achieve.getTotalScore() + Double.valueOf(model.getTotalScore()));
                                                achieve.setAvgScore(achieve.getTotalScore() / achieve.getSubjectCount());
                                                studentAchieveRepository.save(achieve);

                                                if(Double.valueOf(model.getTotalScore()) <= 0) {
                                                    //错题
                                                    String questionNumber = model.getQuestionNumber();
                                                    UploadQuestionModel question = questionMap.get(questionNumber);
                                                    if(question != null) {
                                                        StudentErrorBookEntity errorBook = new StudentErrorBookEntity();
                                                        errorBook.setDifficulty(question.getDifficulty());
                                                        errorBook.setQuestionNumber(questionNumber);
                                                        errorBook.setStudentId(student.getId());
                                                        errorBook.setTitle(question.getTitle());
                                                        errorBook.setTotalScore(question.getTotalScore());
                                                        errorBook.setTrueAnswer(question.getTrueAnswer());

                                                        studentErrorBookRepository.save(errorBook);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            destDir.delete();
                            file.delete();
                        }
                    }
                }
            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    private String readFile(File file) {
        Long length = file.length();
        byte[] content = new byte[length.intValue()];
        try {
            FileInputStream fis = new FileInputStream(file);
            fis.read(content);
            fis.close();
            return new String(content, "GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "";
    }

    private void unzip(String sourceZip,String destDir) throws Exception{
        try{
            Project p = new Project();
            Expand e = new Expand();
            e.setProject(p);
            e.setSrc(new File(sourceZip));
            e.setOverwrite(false);
            e.setDest(new File(destDir));
           /*
           ant下的zip工具默认压缩编码为UTF-8编码，
           而winRAR软件压缩是用的windows默认的GBK或者GB2312编码
           所以解压缩时要制定编码格式
           */
            e.setEncoding("UTF-8");
            e.execute();
        }catch(Exception e){
            throw e;
        }
    }
}